package com.kaikeba.estack.web.mvc;

import com.google.common.io.CharStreams;
import com.kaikeba.estack.common.util.JSONUtil;
import com.kaikeba.estack.exception.ResolveParamException;
import com.kaikeba.estack.web.ApplicationContext;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * 请求参数解析器
 *
 * @Auth xingwan
 * @Date 2020/10/3 1:17
 **/
public class RequestParamResolve {

    /**
     * 解析请求参数
     *
     * @return
     */
    public static Object[] resolve(Method method) {
        int parameterCount = method.getParameterCount();
        //如果参数的个数为0代表
        if (parameterCount == 0) {
            return new Object[0];
        }
        //controller方法的形參
        Parameter[] parameters = method.getParameters();
        Object[] resolveParams = new Object[parameterCount];
        HttpServletRequest request = ApplicationContext.getRequest();
        for (int i = 0; i < parameterCount; i++) {
            Parameter parameter = parameters[i];
            resolveParams[i] = parseRequestParam(parameter, request);
        }
        return resolveParams;
    }

    /**
     * 解析当前的请求参数
     *
     * @param parameter
     * @param request
     * @return
     */
    private static Object parseRequestParam(Parameter parameter, HttpServletRequest request) {
        Class<?> type = parameter.getType();
        /**
         * 如果是HttpServletRequest则直接返回当前请求的request或response
         */
        if (HttpServletRequest.class.isAssignableFrom(type)) {
            return request;
        }
        if (HttpServletResponse.class.isAssignableFrom(type)) {
            return ApplicationContext.getResponse();
        }

        /**
         * 判断是否是requestBody类型的参数
         */
        RequestBody requestBody = parameter.getAnnotation(RequestBody.class);
        if (requestBody != null) {
            //直接解析请求体
            return resolveRequestBody(parameter);
        }

        RequestParam requestParam = parameter.getAnnotation(RequestParam.class);
        String key = parameter.getName();
        if (requestParam != null) {
            key = StringUtils.defaultIfBlank(requestParam.value(), requestParam.name());
        }
        if (StringUtils.isNotBlank(key)) {
            String parameterValue = request.getParameter(key);
            parameterValue = parameterValue == null ? requestParam.defaultValue() : parameterValue;
            return JSONUtil.parseObject(parameterValue, parameter.getType());
        }
        return null;
    }

    /**
     * 解析
     *
     * @param parameter
     * @return
     */
    private static Object resolveRequestBody(Parameter parameter) {
        return JSONUtil.parseObject(getPayload(), parameter.getType());
    }

    /**
     * 获取当前使用payload方式传递的请求体
     *
     * @return
     */
    private static String getPayload() {
        HttpServletRequest request = ApplicationContext.getRequest();
        try (BufferedReader reader = request.getReader()) {
            return CharStreams.toString(reader);
        } catch (IOException e) {
            throw new ResolveParamException(e);
        }
    }
}
